package tests;

import static org.junit.Assert.*;

import java.io.StringReader;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import parsing.CritterParser;
import parsing.productions.AbstractNode;
import parsing.productions.Condition;
import parsing.productions.Conjunction;
import parsing.productions.Program;
import parsing.productions.Relation;
import world.Critter;
import world.CritterWorld;
import world.Hex;
import world.Location;

public class EvaluableNodeTests {

	private static CritterParser parser;
	private static CritterWorld world;
	
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		parser = new CritterParser();
		world = new CritterWorld("constants.txt");
	}

	@Before
	public void setUp() throws Exception {
	}

	@Test
	public void relationTest() {
		//tests false
		Program program = parser.parse(new StringReader(
				"4 > 5 --> left;"));
		AbstractNode node = program;
		for(int i = 0; i < 4; i++)
			node = node.getChildren().get(0);
		Relation relation = (Relation) node;
		Critter crit = new Critter(world, new Hex(world, new Location(world, 0, 0)), 7, 0, 0);
		assertFalse("The Relation's value was not false as expected", relation.eval(crit));
		
		//tests true
		program = parser.parse(new StringReader(
				"4 < 5 --> left;"));
		node = program;
		for(int i = 0; i < 4; i++)
			node = node.getChildren().get(0);
		relation = (Relation) node;
		crit = new Critter(world, new Hex(world, new Location(world, 0, 0)), 7, 0, 0);
		assertTrue("The Relation's value was not true as expected", relation.eval(crit));
		
		//tests {condition} type
		program = parser.parse(new StringReader(
				"{4 < 5} --> left;"));
		node = program;
		for(int i = 0; i < 4; i++)
			node = node.getChildren().get(0);
		relation = (Relation) node;
		crit = new Critter(world, new Hex(world, new Location(world, 0, 0)), 7, 0, 0);
		assertTrue("The Relation's value was not true as expected", relation.eval(crit));
	}

	@Test
	public void conjunctionTest() {
		//tests false
		Program program = parser.parse(new StringReader(
				"3 != 4 and 7 = 7 and 4 > 5 --> left;"));
		AbstractNode node = program;
		for(int i = 0; i < 3; i++)
			node = node.getChildren().get(0);
		Conjunction conjunction = (Conjunction) node;
		Critter crit = new Critter(world, new Hex(world, new Location(world, 0, 0)), 7, 0, 0);
		assertFalse("The Conjunction's value was not false as expected", conjunction.eval(crit));
		
		//tests true
		program = parser.parse(new StringReader(
				"3 != 4 and 7 = 7 and 4 < 5 --> left;"));
		node = program;
		for(int i = 0; i < 3; i++)
			node = node.getChildren().get(0);
		conjunction = (Conjunction) node;
		crit = new Critter(world, new Hex(world, new Location(world, 0, 0)), 7, 0, 0);
		assertTrue("The Conjunction's value was not true as expected", conjunction.eval(crit));
	}

	@Test
	public void conditionTest() {
		//tests false
		Program program = parser.parse(new StringReader(
				"7 = 8 or 4 > 5 --> left;"));
		AbstractNode node = program;
		for(int i = 0; i < 2; i++)
			node = node.getChildren().get(0);
		Condition condition = (Condition) node;
		Critter crit = new Critter(world, new Hex(world, new Location(world, 0, 0)), 7, 0, 0);
		assertFalse("The Condition's value was not false as expected", condition.eval(crit));
		
		//tests true
		program = parser.parse(new StringReader(
				"7 = 8 or 4 < 5 --> left;"));
		node = program;
		for(int i = 0; i < 2; i++)
			node = node.getChildren().get(0);
		condition = (Condition) node;
		crit = new Critter(world, new Hex(world, new Location(world, 0, 0)), 7, 0, 0);
		assertTrue("The Condition's value was not true as expected", condition.eval(crit));
	}

}
